local math = math
local pairs = pairs
local ipairs = ipairs
local type = type
local table = table
local tabletool = require "tabletool"
local timetool = require "timetool"
local base = require "base"
local filelog = require "filelog"
require "enum"

require "cardvalue"

local cardTool = {}

local function calculate_cardtype(card)
    return (card // 16)
end

local function calculate_cardvalue(card)
    return (card % 16)
end

local function comps(card1, card2)
    return card1 > card2
end

local function cards_shuffle(cards)
    -- 洗牌
    local index
    local tmp_seed
    tmp_seed = base.RNG()
    if tmp_seed == nil then
        tmp_seed = timetool.get_10ms_time()
    end

    for i = 1, #CardData do
        math.randomseed(tmp_seed + 11*i)    
        index = math.random(#CardData + 1 - i)
        CardData[index], CardData[#CardData + 1 - i] = CardData[#CardData + 1 - i], CardData[index]
    end
end

--@des 获得新的牌堆
function cardTool.get_new_cards(cards)

    if cards ~= nil then
       return tabletool.deepcopy(cards) 
    end

    cards_shuffle()

    return tabletool.deepcopy(CardData)
end

--@des 获得固定牌型的牌堆
function cardTool.get_fixed_cards(cards)
    math.randomseed(timetool.get_time())

    local index = math.random(#FixedCardData)
    return tabletool.deepcopy(FixedCardData[index]) 
end

--@des 对传入的牌按牌值由大到小排序
function cardTool.from_ztoa_sort(cards)
    table.sort(cards, comps)
end

-- @des 判断是否是对子
function cardTool.is_two(cards)
    if cards == nil or #cards ~= 2 then
        return false
    end

    if calculate_cardtype(cards[1]) == calculate_cardtype(cards[2]) 
        and  calculate_cardvalue(cards[1]) == calculate_cardvalue(cards[2]) then
        return true
    end
    
    return false
end

--@des 判断是否是三张
function cardTool.is_three(cards)
    if cards == nil or #cards ~= 3 then
        return false
    end

    local card_value, card_type
    card_type = calculate_cardtype(cards[1])
    card_value = calculate_cardvalue(cards[1])

    if card_value ~= calculate_cardvalue(cards[2]) 
        or card_type ~= calculate_cardtype(cards[2]) then
        return false
    end

    if card_value ~= calculate_cardvalue(cards[3]) 
        or card_type ~= calculate_cardtype(cards[3]) then
        return false
    end

    return true
end

--@des 判断是否是四张
function cardTool.is_four(cards)
    if cards == nil or #cards ~= 4 then
        return false
    end

    local card_value, card_type
    card_type = calculate_cardtype(cards[1])
    card_value = calculate_cardvalue(cards[1])

    if card_value ~= calculate_cardvalue(cards[2]) 
        or card_type ~= calculate_cardtype(cards[2]) then
        return false
    end

    if card_value ~= calculate_cardvalue(cards[3]) 
        or card_type ~= calculate_cardtype(cards[3]) then
        return false
    end

    if card_value ~= calculate_cardvalue(cards[4]) 
        or card_type ~= calculate_cardtype(cards[4]) then
        return false
    end

    return true    
end


--@des 判断是否是顺子
function cardTool.is_shunzi(cards)
    if cards == nil or #cards ~= 3 then
        return false
    end
    table.sort(cards, comps)
    local tmpcards = {} 
    local card = cards[1]
    table.insert(tmpcards, card)
    for i=2, #cards do
        if calculate_cardvalue(card) - calculate_cardvalue(cards[i]) == 1 
            and calculate_cardtype(card) == calculate_cardtype(cards[i]) then
            table.insert(tmpcards, cards[i])
            card = cards[i]
        else
            return false 
        end
        if #tmpcards >= 3 then
            return true
        end
    end

    return false
end

--@des 判断是否是2,7,10
function cardTool.is_type2710(cards)
    if cards == nil or #cards ~= 3 then
        return false
    end
    table.sort(cards, comps)
    if calculate_cardtype(cards[1]) ~= calculate_cardtype(cards[2]) 
        or calculate_cardtype(cards[1]) ~= calculate_cardtype(cards[3])
        or calculate_cardtype(cards[2]) ~= calculate_cardtype(cards[3]) then
        return false
    end

    if cards[1] == 0x0A 
        and cards[2] == 0x07
        and cards[3] == 0x02 then
        return true
    end

    if cards[1] == 0x1A 
        and cards[2] == 0x17
        and cards[3] == 0x12 then
        return true
    end

    return false
end

--@des 判断是否是搭子
function cardTool.is_dazi(cards)
    if cards == nil or #cards ~= 3 then
        return false
    end

    table.sort(cards, comps)
    local card1_type, card1_value
    local card2_type, card2_value
    local card3_type, card3_value

    card1_type = calculate_cardtype(cards[1])
    card1_value = calculate_cardvalue(cards[1])

    card2_type = calculate_cardtype(cards[2])
    card2_value = calculate_cardvalue(cards[2])

    card3_type = calculate_cardtype(cards[3])
    card3_value = calculate_cardvalue(cards[3])

    if card1_value ~= card2_value 
        or card1_value ~= card3_value
        or card2_value ~= card3_value then
        return false
    end

    if card1_type == card2_type 
        and card1_type == card3_type
        and card2_type == card3_type then
        return false
    end
    return true   
end

function cardTool.calculate_paoqitishe_count(seat)
    local count = 0
    for _, daziitem in ipairs(seat.dazi_cards) do
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PAOQI
            or daziitem.card_action_type == EPHZActionType.ACTION_TYPE_TISHE then
            count = count + 1 
        end
    end
    return count
end

function cardTool.calculate_pengsao_cout(seat)
    local count = 0
    for _, daziitem in ipairs(seat.dazi_cards) do
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PAOQI
            or daziitem.card_action_type == EPHZActionType.ACTION_TYPE_TISHE
            or daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO
            or daziitem.card_action_type == EPHZActionType.ACTION_TYPE_GUOSAO
            or daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PENG then
            count = count + 1 
        end
    end
    return count
end

--@des 生成指定牌堆值的小牌值集合列表
function cardTool.generate_smallcardvalueset_list(cards)
    local cardvalueset_list = {}
    local card_value
    local card_type
    for _, card in ipairs(cards) do
        card_value = calculate_cardvalue(card)
        card_type = calculate_cardtype(card)
        if card_type == 0 then
            if cardvalueset_list[card_value] == nil then
                cardvalueset_list[card_value] = {}
            end 
            table.insert(cardvalueset_list[card_value], card)
        end
    end
    return cardvalueset_list
end

--@des 生成指定牌堆值的大牌值集合列表
function cardTool.generate_bigcardvalueset_list(cards)
    local cardvalueset_list = {}
    local card_value
    local card_type
    for _, card in ipairs(cards) do
        card_value = calculate_cardvalue(card)
        card_type = calculate_cardtype(card)
        if card_type == 1 then
            if cardvalueset_list[card_value] == nil then
                cardvalueset_list[card_value] = {}
            end 
            table.insert(cardvalueset_list[card_value], card)
        end
    end
    return cardvalueset_list
end

--@des 生成指定牌值的集合列表
function cardTool.generate_cardvalueset_list(cards)
    local cardvalueset_list = {}
    local card_value
    for _, card in ipairs(cards) do
        card_value = calculate_cardvalue(card)
        if cardvalueset_list[card_value] == nil then
            cardvalueset_list[card_value] = {}
        end 
        table.insert(cardvalueset_list[card_value], card)
    end
    return cardvalueset_list
end

--@des 计算给定牌的对子数


--@des 传入数据一定是从大到小排序的, 判断是否有完整牌型（三张、顺子、搭子、2710）
function cardTool.is_complete_cardtype(cards)    
   if #cards == 0 then
        return true
    end

    if #cards < 3 then
        return false
    end

    table.sort(cards, comps)

    local card = table.remove(cards, 1)
    local is_find = false
    local recurcards = nil

    for i=1, #cards-1 do
        for j = i+1, #cards do
            --判断是否是三张
            if card == cards[i] and card == cards[j] then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end 
            if is_find then
                return true
            end

            --判断是否顺子
            if calculate_cardtype(card) == calculate_cardtype(cards[i])
                and calculate_cardtype(card) == calculate_cardtype(cards[j]) then
                if (card - cards[i]) == 1 and (cards[i] - cards[j]) == 1 then
                    recurcards = tabletool.deepcopy(cards)
                    table.remove(recurcards, j)
                    table.remove(recurcards, i)
                    is_find = cardTool.is_complete_cardtype(recurcards)                    
                end
            end
            if is_find then
                return true
            end

            --判断是否是搭子
            if calculate_cardvalue(card) == calculate_cardvalue(cards[i]) 
                and calculate_cardvalue(card) == calculate_cardvalue(cards[j]) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end

            if is_find then
                return true
            end

            if card == 2 and ((cards[i] == 7 and cards[j] == 10) 
                or (cards[i] == 10 and cards[j] == 7)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end
            if is_find then
                return true
            end

            if card == 7 and ((cards[i] == 2 and cards[j] == 10) 
                or (cards[i] == 10 and cards[j] == 2)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end
            if is_find then
                return true
            end

            if card == 10 and ((cards[i] == 7 and cards[j] == 2) 
                or (cards[i] == 2 and cards[j] == 7)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end
            if is_find then
                return true
            end

            if card == 0x12 and ((cards[i] == 0x17 and cards[j] == 0x1A) 
                or (cards[i] == 0x1A and cards[j] == 0x17)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end
            if is_find then
                return true
            end

            if card == 0x17 and ((cards[i] == 0x12 and cards[j] == 0x1A) 
                or (cards[i] == 0x1A and cards[j] == 0x12)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end
            if is_find then
                return true
            end

            if card == 0x1A and ((cards[i] == 0x17 and cards[j] == 0x12) 
                or (cards[i] == 0x12 and cards[j] == 0x17)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                is_find = cardTool.is_complete_cardtype(recurcards)
            end
            if is_find then
                return true
            end
        end
    end
    return false
end

function cardTool.calculate_chi(seat, cards, seat_index, seats)     
    local dazi_cards = {}
    if tabletool.is_emptytable(cards) then
        return dazi_cards
    end

    --删除牌
    for _, card in ipairs(cards) do
        tabletool.remove_item(seat.cards, card)
    end
    local daziitem = {cards = {cards[1], cards[2], cards[3]}}
    daziitem.card_action_type = EPHZActionType.ACTION_TYPE_CHI
    daziitem.precard_action_type = 0                
    daziitem.seat_index = seat_index
    daziitem.count = 0
    table.insert(seat.dazi_cards, daziitem)
    table.insert(dazi_cards, daziitem)
    if cards[4] ~= nil then
        daziitem = {cards = {cards[4], cards[5], cards[6]}}
        daziitem.card_action_type = EPHZActionType.ACTION_TYPE_CHILUO
        daziitem.precard_action_type = 0                
        daziitem.seat_index = seat_index
        daziitem.count = 0
        table.insert(seat.dazi_cards, daziitem)
        table.insert(dazi_cards, daziitem)
    end

    if cards[7] ~= nil then
        daziitem = {cards = {cards[7], cards[8], cards[9]}}
        daziitem.card_action_type = EPHZActionType.ACTION_TYPE_CHILUO
        daziitem.precard_action_type = 0                
        daziitem.seat_index = seat_index
        daziitem.count = 0
        table.insert(seat.dazi_cards, daziitem)
        table.insert(dazi_cards, daziitem)
    end

    return dazi_cards
end

function cardTool.calculate_peng(seat, card, seat_index, seats)
    local count = 0
    for _, value in ipairs(seat.dazi_cards) do
        if value.card_action_type == EPHZActionType.ACTION_TYPE_PENG
            or value.card_action_type == EPHZActionType.ACTION_TYPE_TISHE 
            or value.card_action_type == EPHZActionType.ACTION_TYPE_SAO
            or value.card_action_type == EPHZActionType.ACTION_TYPE_GUOSAO
            or value.card_action_type == EPHZActionType.ACTION_TYPE_PAOQI then
            count = count + 1
        end
    end

    --删除牌
    tabletool.remove_item(seat.cards, card, true)

    local daziitem = {cards = {}}
    daziitem.card_action_type = EPHZActionType.ACTION_TYPE_PENG
    daziitem.precard_action_type = 0                
    daziitem.seat_index = seat_index
    daziitem.count = count + 1

    if seat_index == seat.index then
        table.insert(daziitem.cards, card)
        table.insert(daziitem.cards, card)
        table.insert(daziitem.cards, card)
    else
        table.insert(daziitem.cards, card)
        table.insert(daziitem.cards, card)
        table.insert(seats[seat_index].wuda_cards, card)
    end

    table.insert(seat.dazi_cards, daziitem)
    return {[1] = daziitem}
end

function cardTool.calculate_paoqi(seat, card, seat_index, seats)
    if card ~= nil and card ~= 0 then
        for _, daziitem in ipairs(seat.dazi_cards) do
            if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO 
                and daziitem.cards[1] == card then
                table.insert(daziitem.cards, card)
                daziitem.seat_index = seat_index
                daziitem.precard_action_type = EPHZActionType.ACTION_TYPE_SAO
                daziitem.card_action_type = EPHZActionType.ACTION_TYPE_PAOQI
                return {[1]=daziitem}                
            end

            if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PENG
                and daziitem.cards[1] == card
                and seat_index == seat.index then
                if #daziitem.cards == 2 then
                    table.insert(daziitem.cards, card)
                    tabletool.remove_item(seats[daziitem.seat_index].wuda_cards, card)                     
                end
                table.insert(daziitem.cards, card)
                daziitem.precard_action_type = EPHZActionType.ACTION_TYPE_PENG
                daziitem.card_action_type = EPHZActionType.ACTION_TYPE_PAOQI                
                return {[1]=daziitem}
            end
        end
        return nil
    end
    return nil    
end

function cardTool.calculate_tishe(seat, card, seat_index, seats)
    if card ~= nil and card ~= 0 then
        for _, daziitem in ipairs(seat.dazi_cards) do
            if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO
                and daziitem.cards[1] == card then
                daziitem.seat_index = seat_index
                table.insert(daziitem.cards, card)
                daziitem.precard_action_type = EPHZActionType.ACTION_TYPE_SAO                
                daziitem.card_action_type = EPHZActionType.ACTION_TYPE_TISHE
                return {[1]=daziitem}
            end
        end
        return nil
    end

    local is_find = false
    local count = 0
    local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(seat.cards)
    local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(seat.cards)
    for card_value, card_value_set in pairs(small_card_value_set_list) do
        if #card_value_set == 4 then
            count = count + 1
            local daziitem = {
                cards = card_value_set,
                card_action_type = EPHZActionType.ACTION_TYPE_TISHE,
                precard_action_type = 0,                
                seat_index = seat_index,
                count = count,
            }
            table.insert(seat.dazi_cards, daziitem)
            is_find = true
            tabletool.remove_item(seat.cards, card_value_set[1], true)
        end
    end

    for card_value, card_value_set in pairs(big_card_value_set_list) do
        if #card_value_set == 4 then
            count = count + 1
            local daziitem = {
                cards = card_value_set,
                card_action_type = EPHZActionType.ACTION_TYPE_TISHE,
                precard_action_type = 0,
                seat_index = seat_index,
                count = count + 1,
            }
            table.insert(seat.dazi_cards, daziitem)
            is_find = true
            tabletool.remove_item(seat.cards, card_value_set[1], true)
        end
    end
    if is_find then
        return seat.dazi_cards
    end

    return nil
end

function cardTool.calculate_sao(seat, card, seat_index, seats, is_kaiju)
    local is_find = false
    local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(seat.cards)
    local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(seat.cards)

    local count = 0
    for _, value in ipairs(seat.dazi_cards) do
        if value.card_action_type == EPHZActionType.ACTION_TYPE_SAO 
            or value.card_action_type == EPHZActionType.ACTION_TYPE_GUOSAO
            or value.card_action_type == EPHZActionType.ACTION_TYPE_PAOQI
            or value.card_action_type == EPHZActionType.ACTION_TYPE_TISHE
            or value.card_action_type == EPHZActionType.ACTION_TYPE_PENG then
            count = count + 1
        end
    end

    if card ~= nil and card ~= 0 and seat_index > 0 then
        for card_value, card_value_set in pairs(small_card_value_set_list) do
            if #card_value_set == 2 and card == card_value_set[1] then
                count = count + 1
                table.insert(card_value_set, card)
                local daziitem = {
                    cards = card_value_set,
                    seat_index = seat_index,
                    precard_action_type = 0,
                    count = count,
                }
                if seat.notchi_cards[card] then
                    daziitem.card_action_type = EPHZActionType.ACTION_TYPE_GUOSAO
                else
                    daziitem.card_action_type = EPHZActionType.ACTION_TYPE_SAO
                end

                table.insert(seat.dazi_cards, daziitem)
                tabletool.remove_item(seat.cards, card, true)
                return {[1]=daziitem}
            end
        end

        for card_value, card_value_set in pairs(big_card_value_set_list) do
            if #card_value_set == 2 and card == card_value_set[1] then
                count = count + 1
                table.insert(card_value_set, card)
                local daziitem = {
                    cards = card_value_set,
                    seat_index = seat_index,
                    precard_action_type = 0,                
                    count = count,
                }
                if isguosao then
                    daziitem.card_action_type = EPHZActionType.ACTION_TYPE_GUOSAO
                else
                    daziitem.card_action_type = EPHZActionType.ACTION_TYPE_SAO
                end
                table.insert(seat.dazi_cards, daziitem)
                tabletool.remove_item(seat.cards, card, true)
                return {[1]=daziitem}
            end
        end
        return nil        
    end

    for card_value, card_value_set in pairs(small_card_value_set_list) do
        if #card_value_set == 3 then
            count = count + 1
            local daziitem = {
                cards = card_value_set,
                card_action_type = EPHZActionType.ACTION_TYPE_SAO,
                seat_index = seat_index,
                precard_action_type = 0,                
                count = count,
            }
            table.insert(seat.dazi_cards, daziitem)
            is_find = true
            tabletool.remove_item(seat.cards, card_value_set[1], true)
        end
    end

    for card_value, card_value_set in pairs(big_card_value_set_list) do
        if #card_value_set == 3 then
            count = count + 1
            local daziitem = {
                cards = card_value_set,
                card_action_type = EPHZActionType.ACTION_TYPE_SAO,
                seat_index = seat_index,
                precard_action_type = 0,                
                count = count,
            }
            table.insert(seat.dazi_cards, daziitem)
            is_find = true
            tabletool.remove_item(seat.cards, card_value_set[1], true)
        end
    end
    if is_find then
        return seat.dazi_cards
    end

    return nil
end

--@des 判断玩家是否可以扫
function cardTool.is_sao(seat, card, chu_mo_paitag)
    local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(seat.cards)
    local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(seat.cards)

    for _, small_card_set in pairs(small_card_value_set_list) do
        if #small_card_set == 2 and small_card_set[1] == card then
            return true
        end
    end

    for _, big_card_set in pairs(big_card_value_set_list) do
        if #big_card_set == 2 and big_card_set[1] == card then
            return true
        end
    end

    return false
end

--@des 判断玩家是否可以提蛇
function cardTool.is_tishe(seat, card, chu_mo_paitag)
    for _, daziitem in ipairs(seat.dazi_cards) do
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO and daziitem.cards[1] == card then
            return true
        end
    end
    return false    
end

--@des 判断玩家是否可以跑起
function cardTool.is_paoqi(seat, card, chu_mo_paitag)
    for _, daziitem in ipairs(seat.dazi_cards) do
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO and daziitem.cards[1] == card then
            return true
        end
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PENG 
            and daziitem.cards[1] == card
            and chu_mo_paitag == 2 then
            return true
        end
    end
    return false
end

--@des 判断玩家是否可以碰
function cardTool.is_peng(seat, card, chu_mo_paitag, is_hupai)
    local count = 0
    if seat.notpeng_cards[card] ~= nil and not is_hupai then
        return false
    end

    for _, value in ipairs(seat.cards) do
        if value == card then
            count = count + 1
        end
    end

    if count >= 2 and #(seat.cards) > 2 then
        return true
    end
    return false
end

--@des 判断持牌是否可以落完
function cardTool.is_luoall(cards, card)
    local is_find = false
    local index
    for key, value in ipairs(cards) do
        if value == card then
            is_find = true
            index = key
            break
        end
    end

    if not is_find then
        return true
    end
    table.remove(cards, index)
    local recurcards = nil
    for i=1, #cards-1 do
        for j = i+1, #cards do
            --判断是否顺子
            if calculate_cardtype(card) == calculate_cardtype(cards[i])
                and calculate_cardtype(card) == calculate_cardtype(cards[j]) then
                local tmpcards = {card, cards[i], cards[j]}
                table.sort(tmpcards, comps)
                if (tmpcards[1] - tmpcards[2]) == 1 
                    and (tmpcards[2] - tmpcards[3]) == 1 then
                    recurcards = tabletool.deepcopy(cards)
                    table.remove(recurcards, j)
                    table.remove(recurcards, i)
                    if cardTool.is_luoall(recurcards, card) then
                        return true
                    end
                end
            end

            --判断是否是搭子
            if calculate_cardvalue(card) == calculate_cardvalue(cards[i]) 
                and calculate_cardvalue(card) == calculate_cardvalue(cards[j]) then
                if card ~= cards[i] or card ~= cards[j] then
                    recurcards = tabletool.deepcopy(cards)
                    table.remove(recurcards, j)
                    table.remove(recurcards, i)
                    if cardTool.is_luoall(recurcards, card) then
                        return true
                    end
                end
            end

            if card == 2 and ((cards[i] == 7 and cards[j] == 10) 
                or (cards[i] == 10 and cards[j] == 7)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 7 and ((cards[i] == 2 and cards[j] == 10) 
                or (cards[i] == 10 and cards[j] == 2)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 10 and ((cards[i] == 7 and cards[j] == 2) 
                or (cards[i] == 2 and cards[j] == 7)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 0x12 and ((cards[i] == 0x17 and cards[j] == 0x1A) 
                or (cards[i] == 0x1A and cards[j] == 0x17)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 0x17 and ((cards[i] == 0x12 and cards[j] == 0x1A) 
                or (cards[i] == 0x1A and cards[j] == 0x12)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 0x1A and ((cards[i] == 0x17 and cards[j] == 0x12) 
                or (cards[i] == 0x12 and cards[j] == 0x17)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end
        end        
    end
    return false
end

--@des 判断玩家是否可以吃牌
function cardTool.is_chi(seat, card, chu_mo_paitag)
    if seat.notchi_cards[card] ~= nil then
        return false
    end

    if seat.chupai_cards[card] ~= nil then
        return false
    end

    if #(seat.cards) <= 2 then
        return false
    end 

    table.sort(seat.cards, comps)
        
    local cards = seat.cards
    local recurcards = nil 
    for i=1, #cards-1 do
        for j = i+1, #cards do
            --判断是否顺子
            if calculate_cardtype(card) == calculate_cardtype(cards[i])
                and calculate_cardtype(card) == calculate_cardtype(cards[j]) then
                local tmpcards = {card, cards[i], cards[j]}
                table.sort(tmpcards, comps)
                if (tmpcards[1] - tmpcards[2]) == 1 
                    and (tmpcards[2] - tmpcards[3]) == 1 then
                    recurcards = tabletool.deepcopy(cards)
                    table.remove(recurcards, j)
                    table.remove(recurcards, i)
                    if cardTool.is_luoall(recurcards, card) then
                        return true
                    end
                end
            end

            --判断是否是搭子
            if calculate_cardvalue(card) == calculate_cardvalue(cards[i]) 
                and calculate_cardvalue(card) == calculate_cardvalue(cards[j]) then
                if card ~= cards[i] or card ~= cards[j] then
                    recurcards = tabletool.deepcopy(cards)
                    table.remove(recurcards, j)
                    table.remove(recurcards, i)
                    if cardTool.is_luoall(recurcards, card) then
                        return true
                    end
                end
            end

            if card == 2 and ((cards[i] == 7 and cards[j] == 10) 
                or (cards[i] == 10 and cards[j] == 7)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 7 and ((cards[i] == 2 and cards[j] == 10) 
                or (cards[i] == 10 and cards[j] == 2)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 10 and ((cards[i] == 7 and cards[j] == 2) 
                or (cards[i] == 2 and cards[j] == 7)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 0x12 and ((cards[i] == 0x17 and cards[j] == 0x1A) 
                or (cards[i] == 0x1A and cards[j] == 0x17)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 0x17 and ((cards[i] == 0x12 and cards[j] == 0x1A) 
                or (cards[i] == 0x1A and cards[j] == 0x12)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end

            if card == 0x1A and ((cards[i] == 0x17 and cards[j] == 0x12) 
                or (cards[i] == 0x12 and cards[j] == 0x17)) then
                recurcards = tabletool.deepcopy(cards)
                table.remove(recurcards, j)
                table.remove(recurcards, i)
                if cardTool.is_luoall(recurcards, card) then
                    return true
                end
            end
        end        
    end
    return false
end

--@des 判断玩家是否是天胡牌型
function cardTool.is_tianhu_hupaitype(seat, cards, chu_mo_paitag)
    local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(cards)
    local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(cards)

    local tmpcards = tabletool.deepcopy(cards)

    local is_hupai = false
    local recurcards = nil

    local duizi_num = 0
    local three_num = 0
    local four_num = 0
    for _, small_card_set in pairs(small_card_value_set_list) do
        if #small_card_set == 2 then
            duizi_num = duizi_num + 1
        elseif #small_card_set == 3 then
            three_num = three_num + 1
            tabletool.remove_item(tmpcards, small_card_set[1], true)
        elseif #small_card_set == 4 then
            four_num = four_num + 1
            tabletool.remove_item(tmpcards, small_card_set[1], true)
        end
    end
    for _, big_card_set in pairs(big_card_value_set_list) do
        if #big_card_set == 2 then
            duizi_num = duizi_num + 1
        elseif #big_card_set == 3 then
            three_num = three_num + 1
            tabletool.remove_item(tmpcards, big_card_set[1], true)
        elseif #big_card_set == 4 then
            four_num = four_num + 1
            tabletool.remove_item(tmpcards, big_card_set[1], true)
        end
    end

    if #(seat.cards) == 15 and duizi_num >= 6 and three_num >= 1 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_XIAOQIDUIHU
    end

    if #(seat.cards) ~= 15 and duizi_num >= 7 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_XIAOQIDUIHU
    end

    if four_num >= 2 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_SHUANGLONGHU
    end

    if four_num >= 1 then
        for card_value, card_value_set in pairs(small_card_value_set_list) do
            if #card_value_set == 2 then
                recurcards = tabletool.deepcopy(tmpcards)
                tabletool.remove_item(recurcards, card_value_set[1], true)
                is_hupai = cardTool.is_complete_cardtype(recurcards)
                if is_hupai then
                    return true, EPHZHupaiType.PHZHUPAI_TYPE_TIANFU
                end
            end
        end        
        for card_value, card_value_set in pairs(big_card_value_set_list) do
            if #card_value_set == 2 then
                recurcards = tabletool.deepcopy(tmpcards)
                tabletool.remove_item(recurcards, card_value_set[1], true)
                is_hupai = cardTool.is_complete_cardtype(recurcards)
                if is_hupai then
                    return true, EPHZHupaiType.PHZHUPAI_TYPE_TIANFU
                end
            end
        end

        return false, nil
    end

    return cardTool.is_complete_cardtype(tmpcards), EPHZHupaiType.PHZHUPAI_TYPE_TIANFU     
end

--@des 判断玩家是否能够扫胡
function cardTool.is_saohu_hupaitype(seat, card, chu_mo_paitag)
    local is_find = false
    local count = 0

    if seat.chupai_cards[card] then
        return false, nil
    end

    if seat.nothu_cards[card] then
        return false, nil
    end

    if not cardTool.is_sao(seat, card, chu_mo_paitag) then
        return false, nil
    end

    local recurcards = tabletool.deepcopy(seat.cards)
    tabletool.remove_item(recurcards, card, true)
    if not cardTool.is_complete_cardtype(tabletool.deepcopy(recurcards)) then
        local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(recurcards)
        local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(recurcards)
        local tmpcards
        local is_hupai = false
        for _, small_card_set in pairs(small_card_value_set_list) do
            if #small_card_set == 2 then
                tmpcards = tabletool.deepcopy(recurcards)
                tabletool.remove_item(tmpcards, small_card_set[1], true)
                is_hupai = cardTool.is_complete_cardtype(tmpcards)
                if is_hupai then
                    break
                end
            end
        end

        if not is_hupai then
            for _, big_card_set in pairs(big_card_value_set_list) do
                if #big_card_set == 2 then
                    tmpcards = tabletool.deepcopy(recurcards)
                    tabletool.remove_item(tmpcards, big_card_set[1], true)
                    is_hupai = cardTool.is_complete_cardtype(tmpcards)
                    if is_hupai then
                        break
                    end
                end
            end
        end
        if not is_hupai then
            return false, nil
        end
    end

    --计算第几次碰
    local count = cardTool.calculate_pengsao_cout(seat)
    count = count + 1
    if count == 5 and seat.is_warning then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU
    end

    if count == 4 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_SISAOLIANHU
    end

    if count == 3 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_SANSAOLIANHU
    end

    return true, EPHZHupaiType.PHZHUPAI_TYPE_SAOHU
end

--@des 判断玩家是否能够提蛇胡
function cardTool.is_tishehu_hupaitype(seat, card, chu_mo_paitag)
    local is_find = false
    local count = 0

    if seat.chupai_cards[card] then
        return false, nil
    end

    for _, daziitem in ipairs(seat.dazi_cards) do
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO 
            and daziitem.cards[1] == card then
            is_find = true
        end

        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_TISHE then
            count = count + 1
        end
    end

    if not is_find or count >= 2 then
        return false, nil
    end 

    local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(seat.cards)
    local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(seat.cards)

    local is_hupai = false
    local recurcards = nil

    for card_value, card_value_set in pairs(small_card_value_set_list) do
        if #card_value_set == 2 then
            recurcards = tabletool.deepcopy(seat.cards)
            tabletool.remove_item(recurcards, card_value_set[1], true)
            is_hupai = cardTool.is_complete_cardtype(recurcards)
            if is_hupai then
                return true, EPHZHupaiType.PHZHUPAI_TYPE_TISHEHU
            end
        end
    end        

    for card_value, card_value_set in pairs(big_card_value_set_list) do
        if #card_value_set == 2 then
            recurcards = tabletool.deepcopy(seat.cards)
            tabletool.remove_item(recurcards, card_value_set[1], true)
            is_hupai = cardTool.is_complete_cardtype(recurcards)
            if is_hupai then
                return true, EPHZHupaiType.PHZHUPAI_TYPE_TISHEHU
            end
        end
    end

    return false, nil
end

--@des 判断玩家是否可以跑胡
function cardTool.is_paohu_hupaitype(seat, card, chu_mo_paitag)
    local is_find = false
    local count = 0

    if seat.chupai_cards[card] then
        return false, nil
    end

    if seat.nothu_cards[card] then
        return false, nil
    end

    for _, daziitem in ipairs(seat.dazi_cards) do
        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_SAO 
            and daziitem.cards[1] == card then
            is_find = true
        elseif  daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PENG 
            and daziitem.cards[1] == card
            and chu_mo_paitag == 2 then
            is_find = true
        end

        if daziitem.card_action_type == EPHZActionType.ACTION_TYPE_PAOQI then
            count = count + 1
        end
    end


    if not is_find or count >= 2 then
        return false, nil
    end 

    local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(seat.cards)
    local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(seat.cards)

    local is_hupai = false
    local recurcards = nil

    for card_value, card_value_set in pairs(small_card_value_set_list) do
        if #card_value_set == 2 then
            recurcards = tabletool.deepcopy(seat.cards)
            tabletool.remove_item(recurcards, card_value_set[1], true)
            is_hupai = cardTool.is_complete_cardtype(recurcards)
            if is_hupai then
                return true, EPHZHupaiType.PHZHUPAI_TYPE_PAOHU
            end
        end
    end        

    for card_value, card_value_set in pairs(big_card_value_set_list) do
        if #card_value_set == 2 then
            recurcards = tabletool.deepcopy(seat.cards)
            tabletool.remove_item(recurcards, card_value_set[1], true)
            is_hupai = cardTool.is_complete_cardtype(recurcards)
            if is_hupai then
                return true, EPHZHupaiType.PHZHUPAI_TYPE_PAOHU
            end
        end
    end
    return false, nil
end

--@des 判断玩家是否碰胡以及碰胡类型 return 是否碰胡，碰胡类型
function cardTool.is_penghu_hupaitype(seat, card, chu_mo_paitag)
    if seat.chupai_cards[card] then
        return false, nil
    end

    if seat.nothu_cards[card] then
        return false, nil
    end
    local count = 0
    for _, value in ipairs(seat.cards) do
        if value == card then
            count = count + 1
        end
    end
    if count < 2 then
        return false, nil
    end

    local recurcards = tabletool.deepcopy(seat.cards)
    tabletool.remove_item(recurcards, card, true)
    if not cardTool.is_complete_cardtype(tabletool.deepcopy(recurcards)) 
        and not (#recurcards == 2 and recurcards[1] == recurcards[2]) then
        local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(recurcards)
        local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(recurcards)
        local tmpcards
        local is_hupai = false
        for _, small_card_set in pairs(small_card_value_set_list) do
            if #small_card_set == 2 then
                tmpcards = tabletool.deepcopy(recurcards)
                tabletool.remove_item(tmpcards, small_card_set[1], true)
                is_hupai = cardTool.is_complete_cardtype(tmpcards)
                if is_hupai then
                    break
                end
            end
        end

        if not is_hupai then
            for _, big_card_set in pairs(big_card_value_set_list) do
                if #big_card_set == 2 then
                    tmpcards = tabletool.deepcopy(recurcards)
                    tabletool.remove_item(tmpcards, big_card_set[1], true)
                    is_hupai = cardTool.is_complete_cardtype(tmpcards)
                    if is_hupai then
                        break
                    end
                end
            end
        end
        if not is_hupai then
            return false, nil
        end
    end

    --计算第几次碰
    count = cardTool.calculate_pengsao_cout(seat)
    count = count + 1
    if count == 5 and seat.is_warning then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU
    end

    if count == 4 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_SIPENGLIANHU
    end

    if count == 3 then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_SANPENGLIANHU
    end

    return true, EPHZHupaiType.PHZHUPAI_TYPE_PENGHU
end

--@des 判断玩家是否能够吃胡
function cardTool.is_chihu_hupaitype(seat, card, chu_mo_paitag)
    if seat.chupai_cards[card] then
        return false, nil
    end

    if seat.nothu_cards[card] or seat.is_warning then
        return false, nil
    end

    local recurcards = tabletool.deepcopy(seat.cards)
    table.insert(recurcards, card)
    local is_hupai = cardTool.is_complete_cardtype(tabletool.deepcopy(recurcards))

    if not is_hupai then
        tabletool.remove_item(recurcards, card, true)
        is_hupai = cardTool.is_complete_cardtype(recurcards)
        if is_hupai then
            return true, EPHZHupaiType.PHZHUPAI_TYPE_CHIHU
        end
    end

    if not is_hupai then
        local small_card_value_set_list = cardTool.generate_smallcardvalueset_list(seat.cards)
        local big_card_value_set_list = cardTool.generate_bigcardvalueset_list(seat.cards)

        for _, small_card_set in pairs(small_card_value_set_list) do
            if #small_card_set == 2 then
                recurcards = tabletool.deepcopy(seat.cards)
                tabletool.remove_item(recurcards, small_card_set[1], true)
                table.insert(recurcards, card)
                is_hupai = cardTool.is_complete_cardtype(recurcards)
                if is_hupai then
                    return true, EPHZHupaiType.PHZHUPAI_TYPE_CHIHU
                end
            end
        end
        for _, big_card_set in pairs(big_card_value_set_list) do
            if #big_card_set == 2 then
                recurcards = tabletool.deepcopy(seat.cards)
                tabletool.remove_item(recurcards, big_card_set[1], true)
                table.insert(recurcards, card)
                is_hupai = cardTool.is_complete_cardtype(recurcards)
                if is_hupai then
                    return true, EPHZHupaiType.PHZHUPAI_TYPE_CHIHU
                end
            end
        end
    end

    if is_hupai then
        return true, EPHZHupaiType.PHZHUPAI_TYPE_CHIHU
    else
        return false, nil
    end   
end

--@des seat座位上玩家 doactionntcmsg 用于返回玩家可以进行的操作类型
function cardTool.analyse_player_action(seat, doactionntcmsg,chu_mo_paitag, chu_mo_pai_card, chu_mo_pai_seat_index, is_check_dihu, isforcehu)    
    if doactionntcmsg.action_types == nil then
        doactionntcmsg.action_types = {}
    end

    local is_hupai, hupai_type
    is_hupai = false
    hupai_type = 0
    if chu_mo_paitag == 0 then
        is_hupai, hupai_type = cardTool.is_tianhu_hupaitype(seat, seat.cards)
        if is_hupai then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
            doactionntcmsg.hupai_type = hupai_type
        end
        return
    end

    if #(seat.cards) == 1 
        and seat.cards[1] == chu_mo_pai_card
        and seat.nothu_cards[chu_mo_pai_card] == nil 
        and seat.chupai_cards[chu_mo_pai_card] == nil then
        table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
        --[[local count = cardTool.calculate_pengsao_cout(seat)
        if count >= 4 and  then
            doactionntcmsg.hupai_type = EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU
        else
        end]]
        doactionntcmsg.hupai_type = EPHZHupaiType.PHZHUPAI_TYPE_CHIHU
        return
    end

    if chu_mo_paitag == 1 then
        is_hupai, hupai_type = cardTool.is_paohu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
        if is_hupai then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
            if is_check_dihu then
                doactionntcmsg.hupai_type = EPHZHupaiType.PHZHUPAI_TYPE_PAODIHU
            else
                doactionntcmsg.hupai_type = hupai_type
            end
        end

        if not is_hupai then
            is_hupai, hupai_type = cardTool.is_penghu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
            if is_hupai then
                table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
                --[[local index = chu_mo_pai_seat_index
                if index + 2 > 4 then
                    index = (index + 2) % 4
                end]]
                --if is_check_dihu and index == seat.index then
                if is_check_dihu then
                    doactionntcmsg.hupai_type = EPHZHupaiType.PHZHUPAI_TYPE_PENGDIHU
                else
                    doactionntcmsg.hupai_type = hupai_type
                end
            end
        end
        if not is_hupai then
            is_hupai, hupai_type = cardTool.is_chihu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
            if is_hupai then
                table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
                --[[local index = chu_mo_pai_seat_index
                if index + 2 > 4 then
                    index = (index + 2) % 4
                end]]
                --if is_check_dihu and index == seat.index then
                if is_check_dihu then
                    doactionntcmsg.hupai_type = EPHZHupaiType.PHZHUPAI_TYPE_DIFU
                else
                    doactionntcmsg.hupai_type = hupai_type
                end
            end
        end

        if not is_hupai 
            or (is_hupai and (isforcehu == nil or isforcehu ~= 1) 
                and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_GUO)
        end

        --判断玩家是否能跑起
        if cardTool.is_paoqi(seat, chu_mo_pai_card, chu_mo_paitag) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_PAOQI)            
            return
        end

        --判断玩家是否能够碰
        if cardTool.is_peng(seat, chu_mo_pai_card, chu_mo_paitag) 
            and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU
            and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_SAOHU
            and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_SANSAOLIANHU
            and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_SISAOLIANHU then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_PENG)            
        end

        --判断玩家是否能够吃
        chu_mo_pai_seat_index = chu_mo_pai_seat_index + 1
        if chu_mo_pai_seat_index > 4 then
            chu_mo_pai_seat_index = chu_mo_pai_seat_index % 4
        end
        if chu_mo_pai_seat_index == seat.index and cardTool.is_chi(seat, chu_mo_pai_card, chu_mo_paitag) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_CHI)            
        end
        return
    end

    if seat.index == chu_mo_pai_seat_index then
        is_hupai, hupai_type = cardTool.is_tishehu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
        if is_hupai then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
            doactionntcmsg.hupai_type = hupai_type
        end

        if not is_hupai then
            is_hupai, hupai_type = cardTool.is_saohu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
            if is_hupai then
                table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
                doactionntcmsg.hupai_type = hupai_type                        
            end
        end
    end

    if seat.index == chu_mo_pai_seat_index and not is_hupai then
        if cardTool.is_tishe(seat, chu_mo_pai_card, chu_mo_paitag) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_TISHE)
            return            
        end

        if cardTool.is_sao(seat, chu_mo_pai_card, chu_mo_paitag) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_SAO)
            return            
        end
    end

    if not is_hupai then
        is_hupai, hupai_type = cardTool.is_paohu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
        if is_hupai then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
            doactionntcmsg.hupai_type = hupai_type
        end
    end

    if not is_hupai then
        is_hupai, hupai_type = cardTool.is_penghu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
        if is_hupai then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
            doactionntcmsg.hupai_type = hupai_type                    
        end
    end

    if not is_hupai then
        is_hupai, hupai_type = cardTool.is_chihu_hupaitype(seat, chu_mo_pai_card, chu_mo_paitag)
        if is_hupai then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_HUPAI)
            doactionntcmsg.hupai_type = hupai_type                    
        end
    end

    if not is_hupai 
            or (is_hupai and (isforcehu == nil or isforcehu ~= 1) 
                and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU) then
        table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_GUO)
    end

    if seat.index == chu_mo_pai_seat_index then
        if cardTool.is_tishe(seat, chu_mo_pai_card, chu_mo_paitag) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_TISHE)
            return            
        end

        if cardTool.is_sao(seat, chu_mo_pai_card, chu_mo_paitag) then
            table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_SAO)
            return            
        end
    end

    --判断玩家是否能跑起
    if cardTool.is_paoqi(seat, chu_mo_pai_card, chu_mo_paitag) then
        table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_PAOQI)
        return
    end

    --判断玩家是否能够碰
    if cardTool.is_peng(seat, chu_mo_pai_card, chu_mo_paitag) 
        and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_WUFUHU
        and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_SAOHU
        and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_SANSAOLIANHU
        and hupai_type ~= EPHZHupaiType.PHZHUPAI_TYPE_SISAOLIANHU then
        table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_PENG)            
    end

    --判断玩家是否能够吃
    if seat.index == chu_mo_pai_seat_index and cardTool.is_chi(seat, chu_mo_pai_card, chu_mo_paitag) then
        table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_CHI)
        return            
    end

    chu_mo_pai_seat_index = chu_mo_pai_seat_index + 1
    if chu_mo_pai_seat_index > 4 then
        chu_mo_pai_seat_index = chu_mo_pai_seat_index % 4
    end
    if seat.index == chu_mo_pai_seat_index and cardTool.is_chi(seat, chu_mo_pai_card, chu_mo_paitag) then
        table.insert(doactionntcmsg.action_types, EPHZActionType.ACTION_TYPE_CHI)
        return            
    end
end 

return cardTool
